home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / C / Applications / Telnet 2.7b5 / source / main / event.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-06-20  |  28.0 KB  |  1,015 lines  |  [TEXT/CWIE]

  1. /*
  2. *    event.c
  3. *****************************************************************
  4. *    NCSA Telnet for the Macintosh                                *
  5. *                                                                *
  6. *    National Center for Supercomputing Applications                *
  7. *    Software Development Group                                    *
  8. *    152 Computing Applications Building                            *
  9. *    605 E. Springfield Ave.                                        *
  10. *    Champaign, IL  61820                                        *
  11. *                                                                *
  12. *    Copyright (c) 1986-1993,                                    *
  13. *    Board of Trustees of the University of Illinois                *
  14. *****************************************************************
  15. *
  16. *    Main Event loop code for NCSA Telnet for the Macintosh
  17. *
  18. *    Called by:
  19. *        maclook.c
  20. *
  21. *    Revisions:
  22. *    7/92    Telnet2.6:    added 2 support for 2 global structs, put cursors into
  23. *                        an array, cleaned up defines            Scott Bulmahn                        
  24. *
  25. */
  26.  
  27. #ifdef MPW
  28. #pragma segment 4
  29. #endif
  30.  
  31. /*
  32.  *    Files for inclusion.
  33.  */
  34.  
  35.  
  36. #include "VSkeys.h"
  37. #include "wind.h"
  38. #include "event.h"     //kxplate moved to its own file (CCP 2.7)
  39. #include "errors.proto.h"
  40. #include "network.proto.h"
  41. #include "mydnr.proto.h"
  42. #include "bkgr.proto.h"
  43. #include "maclook.proto.h"
  44. #include "InternalEvents.h"
  45. #include "vsdata.h"
  46. #include "vsinterf.proto.h"
  47. #include "menuseg.proto.h"
  48. #include "vrrgmac.proto.h"
  49. #include "tekrgmac.proto.h"
  50. #include "rsinterf.proto.h"
  51. #include "rsmac.proto.h"
  52. #include "event.proto.h"
  53. #include "macros.proto.h"                /* For setmacro proto */
  54. #include "netevent.proto.h"
  55. #include "translate.proto.h"
  56. #include "parse.proto.h"
  57. #include "linemode.proto.h"
  58. #include "Connections.proto.h"
  59. #include "mainseg.proto.h"
  60. #include <Script.h> // for EMACS meta hack
  61. #include <Icons.h> //For Notify User Icon Stuff
  62. extern short        scrn;
  63. extern MenuHandle    myMenus[NMENUS];
  64. extern Boolean        gKeyboardHasControlKey;
  65. extern SysEnvRec    theWorld;        /* BYU 2.4.12 - System Environment record */
  66. extern WindRec        *screens,
  67.                     *ftplog;
  68. extern Cursor        *theCursors[];
  69. extern Boolean         gHaveDragMgr;
  70.  
  71. static gHaveInstalledNotification = 0;
  72. NMRec *nRecPtr;
  73.  
  74. #include "event.proto.h"
  75.  
  76. short updateCursor(short force)
  77. {
  78.     static Point    lastPoint;
  79.     static short    optwasdown;
  80.     short            optDown;
  81.     Point            myPoint;
  82.     KeyMap            allthekeys;            /* Someplace to put the keymap */
  83.  
  84.     if (TelInfo->myfrontwindow) {                    /* BYU 2.4.11 */
  85.         SetPort((GrafPtr) TelInfo->myfrontwindow);    /* BYU 2.4.11 */
  86.     } else {                                /* BYU 2.4.11 */
  87.         SetCursor(theCursors[normcurs]);                /* BYU 2.4.11 */
  88.         return(0);                            /* BYU 2.4.11 */
  89.     }
  90.  
  91.     GetMouse(&myPoint);
  92.  
  93.     GetKeys(allthekeys);
  94.     optDown = ((unsigned char *)allthekeys)[7] &4;
  95.  
  96.     if ( (!force) && EqualPt(myPoint,lastPoint) && (optDown ==optwasdown))
  97.         return(0);
  98.  
  99.     if (force)
  100.         TelInfo->lastCursor=0L;
  101.     if (TelInfo->ginon) {
  102.         if (TelInfo->lastCursor!= theCursors[gincurs]) {
  103.             SetCursor(theCursors[gincurs]);
  104.             TelInfo->lastCursor = theCursors[gincurs];
  105.             }
  106.         return(1);
  107.         }
  108.  
  109.     if (TelInfo->xferon && !optDown) {
  110.         if  (TelInfo->lastCursor!= theCursors[xfercurs]) {
  111.             SetCursor( theCursors[xfercurs]);
  112.             TelInfo->lastCursor = theCursors[xfercurs];
  113.             }
  114.         return(1);
  115.         }
  116.  
  117.     switch (TelInfo->myfronttype) {
  118.         case DEC_WINDOW:
  119.             if (RSmouseintext( TelInfo->myfrontvs, myPoint)) 
  120.             {
  121.             
  122.                 if ((PointInSelection(normalize(myPoint, TelInfo->myfrontvs, FALSE),
  123.                             TelInfo->myfrontvs))&&(gHaveDragMgr)) //for Drag ability
  124.                     
  125.                 {
  126.                     if (TelInfo->lastCursor != theCursors[normcurs]) 
  127.                     {
  128.                         TelInfo->lastCursor  = theCursors[normcurs];
  129.                         SetCursor(theCursors[normcurs]);
  130.                     }
  131.                 }
  132.                 else
  133.                 {
  134.                     if (optDown)                /* Option key is down */
  135.                     {
  136.                         if (TelInfo->lastCursor != theCursors[poscurs]) 
  137.                         {
  138.                             TelInfo->lastCursor  = theCursors[poscurs];
  139.                             SetCursor(theCursors[poscurs]);
  140.                         }
  141.                     } 
  142.                     else 
  143.                     {
  144.                         if (TelInfo->lastCursor != theCursors[textcurs]) 
  145.                         {
  146.                             TelInfo->lastCursor  = theCursors[textcurs];
  147.                             SetCursor(theCursors[textcurs]);
  148.                         }
  149.                     }
  150.                 }
  151.             } 
  152.             else 
  153.             {
  154.                 if (TelInfo->lastCursor != theCursors[normcurs]) 
  155.                 {
  156.                     TelInfo->lastCursor  = theCursors[normcurs];
  157.                     SetCursor(theCursors[normcurs]);
  158.                 }
  159.             }
  160.             break;
  161.         case TEK_WINDOW:
  162.             LocalToGlobal(&myPoint);
  163.             if (PtInRgn(myPoint, TelInfo->myfrontwindow->contRgn)) {        /* BYU LSC */
  164.                 if (TelInfo->lastCursor != theCursors[graphcurs]) {
  165.                     TelInfo->lastCursor  = theCursors[graphcurs];
  166.                     SetCursor(theCursors[graphcurs]);
  167.                     }
  168.             } else {
  169.                 if (TelInfo->lastCursor != theCursors[normcurs]) {
  170.                     TelInfo->lastCursor  = theCursors[normcurs];
  171.                     SetCursor(theCursors[normcurs]);
  172.                     }
  173.             }
  174.             break;
  175.         case NO_WINDOW:
  176.         default:
  177.             if (force) {
  178.                 SetCursor( theCursors[normcurs]);
  179.                 TelInfo->lastCursor= theCursors[normcurs];
  180.                 }
  181.         }
  182.     lastPoint=myPoint;
  183.     optwasdown=optDown;
  184.     return(0);
  185. }
  186.  
  187. void NoWindow( void)
  188. {
  189.         TelInfo->myfrontwindow=0L;
  190.         TelInfo->myfronttype=NO_WINDOW;
  191.         TelInfo->myfrontRgn=0L;
  192.         updateCursor(1);
  193. }
  194.  
  195. /*     The following code was graciously donated by Marc Tamsky.  When are YOU going to donate
  196.     YOUR code, eh?  We know you're reading this.  -- JMB */
  197.  
  198. Boolean CheckPageKeys(short code)                                            /* NCSA: SB */
  199. {                                                                            /* NCSA: SB */
  200.     GrafPtr currFW;     // current front window holder                      // MAT--
  201.     short     ourW;       // virtual screen number holder                     // MAT--kinda
  202.     short     x1, y2, x2, y1; // coordinates from window                      // MAT--pulled from scrollproc
  203.                                                                             /* NCSA: SB */
  204.     currFW = (GrafPtr)FrontWindow();                                        // MAT--
  205.     ourW = RSfindvwind(currFW);                                             // MAT--
  206.                                                                             /* NCSA: SB */    
  207.     switch (code)                                                            /* NCSA: SB */
  208.         {                                                                    /* NCSA: SB */
  209.         case VSPGUP:                                                        /* NCSA: SB */
  210.             RScursblinkoff(ourW);
  211.             VSgetrgn(ourW, &x1, &y1, &x2, &y2);                               // MAT--
  212.             VSscrolback(ourW, y2 - y1); /* scroll a whole windowful */      // MAT--
  213.             return TRUE;                                                       // MAT--
  214.             break;                                                            /* NCSA: SB */                                                            
  215.                                                                             /* NCSA: SB */
  216.         case VSPGDN:                                                           // MAT--121 is a PAGE DOWN.                                                                          
  217.             RScursblinkoff(ourW);                                                                // MAT--in rsmac.c
  218.             VSgetrgn(ourW, &x1, &y1, &x2, &y2);                             // MAT--
  219.             VSscrolforward(ourW, y2 - y1); /* scroll a whole windowful */   // MAT--
  220.             return TRUE;                                                    // MAT--
  221.             break;                                                             /* NCSA: SB */
  222.                                                                               // MAT--
  223.         case VSHOME:                                                        /* NCSA: SB */
  224.             RScursblinkoff(ourW);
  225.             VSscroltop(ourW);                                                /* JMB 2.6 -- Created VSscroltop just for this purpose */
  226.             return TRUE;                                                    /* NCSA: SB */
  227.             break;                                                             // MAT--
  228.                                                                                // MAT--
  229.         case VSEND:                                                            /* NCSA: SB */
  230.             RScursblinkoff(ourW);
  231.             VSgetrgn(ourW, &x1, &y1, &x2, &y2);                             // MAT--
  232.             VSscrolforward(ourW, 32765); /* scroll a whole BUNCH! */        // MAT-- kludge time again.  anyone suggest
  233.             return TRUE;                                                    /* NCSA: SB */
  234.             break;                                                             // MAT--  a better way to hack this part?
  235.         }                                                                   // MAT--
  236.                                                                             /* NCSA: SB */
  237.     return FALSE;            /* NCSA: SB - we didnt handle event, let us know about it */
  238. }                                                                            /* NCSA: SB */
  239.  
  240.  
  241. /*  HandleKeyDown --
  242.         By now, we have already gotten a keypress signal from the event handler, so we
  243.         just need to interpret it.  Get the    raw code and ascii value, and then decide
  244.         what to do with it.    */    
  245.  
  246. void HandleKeyDown(EventRecord theEvent,struct WindRec *tw)
  247. {
  248.     unsigned char ascii, code;
  249.     unsigned char sendch;
  250.     long    menuEquiv;
  251.     short    enterkey = 0;
  252.     Boolean    commanddown, optiondown, controldown,shifted;
  253.     ObscureCursor();
  254.     
  255.     ascii = theEvent.message & charCodeMask;
  256.     code = ((theEvent.message & keyCodeMask) >> 8);
  257.     commanddown = ((theEvent.modifiers & cmdKey) != 0);
  258.     optiondown = ((theEvent.modifiers & optionKey) != 0);
  259.     controldown = ((theEvent.modifiers & controlKey) != 0);
  260.     shifted = ((theEvent.modifiers & shiftKey) != 0);
  261.     if (DebugKeys(commanddown, ascii, tw->vs))
  262.         return;
  263.  
  264.     if ((tw->emacsmeta == 2)&&(optiondown))
  265.         goto emacsHack;  //ha ha hack hack
  266.  
  267.     if ((code == 0x34)&&(ascii == 3)) //fix for PowerBook 540  bad KCHR
  268.         ascii = 13;                 //(map control-c to return)
  269.     else if ((controldown)&&(shifted)&&(ascii == '2'))
  270.         ascii = 0;//fix bad KCHR control-@
  271.     else if ((controldown)&&(shifted)&&(ascii == '6'))
  272.         ascii = 0x1e;//fix bad KCHR control-^
  273.  
  274.     if (commanddown)          
  275.     { 
  276.         if (gApplicationPrefs->CommandKeys)
  277.         {
  278.             //if optioned, retranslate so we can do menu commands
  279.             if (optiondown)
  280.             {
  281.                 short virtualCode = 0;
  282.                 Ptr KCHRPtr;
  283.                 long newStuff;
  284.                 unsigned long state = 0;
  285.                 short modifiersCopy;
  286.                 modifiersCopy = theEvent.modifiers;
  287.                 virtualCode = (short)(code);
  288.                 
  289.                 theEvent.modifiers &= (shiftKey); //turn off option
  290.                 virtualCode |= theEvent.modifiers;  
  291.                 KCHRPtr  = (Ptr)GetScriptManagerVariable(smKCHRCache);
  292.                 newStuff = KeyTranslate(KCHRPtr,virtualCode,&state);
  293.                 newStuff &= 0xFF; //only look at bottom byte
  294.                 ascii = (unsigned char) newStuff;
  295.                 theEvent.modifiers = modifiersCopy; //reset option state
  296.             }
  297.  
  298.             menuEquiv = MenuKey(ascii); //handle menu keys first
  299.             if ((menuEquiv & 0xFFFF0000) != 0) 
  300.             {
  301.                 HandleMenuCommand(menuEquiv,theEvent.modifiers);
  302.                 return;
  303.             }
  304.             if ((TelInfo->numwindows < 1) || (tw->active != CNXN_ACTIVE)) 
  305.                 return;
  306.             //    Check for EMACS meta key.  
  307.             if ((tw->emacsmeta)&&(controldown))
  308.             {        
  309.                 unsigned char temp[2];
  310.                 if (ascii <= 32) //control changed the ascii value
  311.                     ascii |= 0x40; //move back to a non-control
  312.                 if ((shifted)||(ascii == 0x5f)) //so we can get meta -
  313.                 {
  314.                     short virtualCode = 0;
  315.                     Ptr KCHRPtr;
  316.                     long newStuff;
  317.                     unsigned long state = 0;
  318.                     virtualCode = (short)(code);
  319.                     theEvent.modifiers &= (shiftKey); //turn of command
  320.                     virtualCode |= theEvent.modifiers;  
  321.                     KCHRPtr  = (Ptr)GetScriptManagerVariable(smKCHRCache);
  322.                     newStuff = KeyTranslate(KCHRPtr,virtualCode,&state);
  323.                     newStuff &= 0xFF; //only look at bottom byte
  324.                     ascii = (unsigned char) newStuff;
  325.                 }
  326.     emacsHack: //if the option key KCHR is installled, we will get the right ascii value
  327.                 if ((tw->clientflags & PASTE_IN_PROGRESS)&&(tw->pastemethod)) //queue this
  328.                 {
  329.                     tw->kbbuf[tw->kblen++] = ESC;
  330.                     tw->kbbuf[tw->kblen++] = ascii;
  331.                     return;
  332.                 }
  333.                 if (tw->kblen > 0)
  334.                 {
  335.                     netwrite( tw->port,tw->kbbuf,tw->kblen);                                        
  336.                     tw->kblen=0;                                                
  337.                 }
  338.                     
  339.                 temp[0] = ESC;
  340.                 temp[1] = ascii;
  341.                 if (tw->echo && tw->halfdup)         
  342.                     parse(tw,temp,2);    
  343.                 netpush(tw->port);            
  344.                 netwrite(tw->port,temp,2);    
  345.                 return;                                            
  346.             }
  347.             else if (ascii >='0' && ascii <='9' )  //now look for macros
  348.             {
  349.                 sendmacro(tw, ascii-'0');
  350.                 return;
  351.             }
  352.             else if (!((ascii == '`' && gApplicationPrefs->RemapTilde)||(code == BScode)))
  353.                 return;
  354.         }
  355.         else //no command key menus
  356.         {
  357.             if ((TelInfo->numwindows < 1) || (tw->active != CNXN_ACTIVE)) 
  358.                 return;
  359.             else if (!gKeyboardHasControlKey) //map command to control
  360.             {
  361.                 ascii &= 0x1f;
  362.                 commanddown = FALSE;
  363.             }
  364.             else
  365.                 return;
  366.         }
  367.     } else if ((TelInfo->numwindows < 1) || (tw->active != CNXN_ACTIVE)) 
  368.         return;
  369.  
  370.  
  371.     if (((ascii == '@') || (ascii == 32))&& controldown) //this, along with the fixed KCHR that mapps a Cntl-@ to
  372.         ascii = NULL;                 //a @, takes care of Apple not posting NULL key values
  373.     
  374.     //    map '`' to ESC if needed
  375.     if (ascii == '`' && gApplicationPrefs->RemapTilde && !(commanddown))
  376.         ascii = ESC;
  377.     
  378.     if (code == BScode) //handle mapping BS to DEL, flipping on option
  379.     {
  380.         if (tw->bsdel)
  381.             if ((optiondown)||(commanddown))
  382.                 ascii = BS;
  383.             else
  384.                 ascii = DEL;
  385.         else
  386.             if ((optiondown)||(commanddown))
  387.                 ascii = DEL;
  388.             else
  389.                 ascii = BS;
  390.     }
  391.         
  392.     if (!tw->enabled) //if we are suspended, and we have negotiated restart_any 
  393.     {                //with the host, then enable the screen on anything but an XOFF.  We will
  394.                     //eat the XON later if that is what this is. (RFC 1372 --CCP 2.7)
  395.         if ((tw->restart_any_flow)&&(ascii != tw->TELstop))
  396.             tw->enabled = 1;
  397.     }
  398.  
  399.     /* Remap PgUp,PgDown,Home,End if the user wants it that way */
  400.     if ((tw->pgupdwn && (code >= KPlowest))||(!tw->vtemulation)) //do page up/down on vt100
  401.         if (CheckPageKeys(code)) return;        
  402.  
  403.     if (code >= KPlowest)         /* BYU - Handle Keypad */
  404.     {
  405.         if (theWorld.keyBoardType == envStandADBKbd)    //standard MacII keyboard has keypad +,- 
  406.         {                                                // codes switched    
  407.             if (code == 0x45)                                    
  408.                 code = 0x4e;
  409.             else if (code == 0x4e)
  410.                 code = 0x45;
  411.         }
  412.  
  413.         if ((tw->vtemulation)||(code >= 0x7B)||(code <= 0x60)) //fkeys dont work in vt100
  414.         {
  415.             if ((!tw->keypadmap)||(code == 0x4c)||(code > 0x51)||(code < 0x43)) //dont remap operators
  416.             {
  417.                 if ((tw->clientflags & PASTE_IN_PROGRESS)&&(tw->pastemethod)) //queue this
  418.                 {
  419.                     tw->kbbuf[tw->kblen++] = 0;
  420.                     tw->kbbuf[tw->kblen++] = kpxlate[shifted][code - KPlowest];
  421.                     return;
  422.                 }
  423.     
  424.                 if (tw->kblen > 0)
  425.                 {
  426.                     netwrite( tw->port,tw->kbbuf,tw->kblen);                                        
  427.                     tw->kblen=0;                                                
  428.                 }
  429.     
  430.                 ascii = kpxlate[shifted][code - KPlowest];
  431.                 // Should we check here for ascii being zero?
  432.                 VSkbsend(tw->vs, (unsigned char) ascii, tw->echo);
  433.                 return;
  434.             }
  435.         }
  436.         else // we dont handle function keys in vt100
  437.             return;
  438.     }
  439.  
  440.     //    Handle whatever mapping is needed.
  441.     mac_nat(&ascii, tw->national); /* LU/PM: Convert char from mac to nat */
  442.     
  443.     if ((tw->clientflags & PASTE_IN_PROGRESS)&&(tw->pastemethod)) //queue this
  444.     {
  445.         tw->kbbuf[tw->kblen++] = ascii;
  446.         return;
  447.     }
  448.  
  449.     if (tw->lmode)    // Some form of linemode is active; we dont touch it after them
  450.     {
  451.         process_key(ascii,tw);
  452.         return;
  453.     }
  454.     
  455.     
  456.     // BSD-like mapping.... if we don't want this, set chars to zero and it wont work
  457.     //CCP 2.7: this is now AFTER the linemode stuff, so that linemode can handle it differently 
  458.     if (ascii == tw->TELstop)
  459.     {
  460.         if (tw->allow_flow) //remote flow control can turn this off
  461.         {
  462.             tw->enabled = 0;
  463.             return;
  464.         }
  465.     }
  466.  
  467.     if (ascii == tw->TELgo) 
  468.     {
  469.         if (tw->allow_flow) //remote flow control can turn this off
  470.         {
  471.             tw->enabled = 1;
  472.             return;
  473.         }
  474.     }        
  475.     if (ascii == tw->TELip)  
  476.     {
  477.         char *tellUser = "\n\r[Interrupt Process]\n\r";
  478.         parse(tw,(unsigned char *)tellUser,23);
  479.         netpush(tw->port);
  480.         netwrite(tw->port, "\377\364",2);            //IAC IP 
  481.         netpush(tw->port);
  482.         netwrite(tw->port, "\377\375\006",3);        // send Do TM 
  483.         tw->timing = 1;                            // set emulate to TMwait 
  484.         return;
  485.     }
  486.     
  487.  
  488.     if (tw->echo && !tw->halfdup)    // Handle klude-linemode
  489.     {
  490.         if (ascii>31 && ascii <127 && code < KPlowest)    
  491.         {
  492.             if (tw->kblen < (MAXKB -1))     /* Add to buffer if not full */
  493.                 tw->kbbuf[tw->kblen++] = ascii;
  494.             else 
  495.             {            /* if full send buffer */            
  496.                 netwrite( tw->port, tw->kbbuf,tw->kblen);    
  497.                 tw->kbbuf[0] = ascii;
  498.                 tw->kblen=1;
  499.             }
  500.  
  501.             sendch=ascii;
  502.             parse(tw, &sendch, 1);
  503.             return;                                /* OK, were set...*/
  504.         
  505.         } //end if printable key 
  506.         else 
  507.         {
  508.             if ( code == BScode ) 
  509.             {
  510.                 if (tw->kblen>0) 
  511.                 {
  512.                     tw->kblen--;
  513.                     parse(tw,(unsigned char *) "\010 \010",3);    /* BYU LSC */
  514.                 }
  515.                 return;
  516.             }
  517.             else if (ascii == KILLCHAR) 
  518.             {
  519.                 while (tw->kblen >0) 
  520.                 {
  521.                     parse(tw,(unsigned char *) "\010 \010",3);    /* BYU LSC */
  522.                     tw->kblen--;
  523.                 }
  524.                 return;
  525.             }
  526.             else if (code <KPlowest) 
  527.             {
  528.                 netwrite( tw->port, tw->kbbuf,tw->kblen);    /* if full send buffer */
  529.                 tw->kblen=0;
  530.                 if (ascii !=CR) 
  531.                 {
  532.                     sendch='@'+ascii;
  533.                     parse(tw,(unsigned char *) "^",1);    /* BYU LSC */
  534.                     parse(tw, &sendch, 1);
  535.                 }
  536.             }
  537.         }//end else non-printable key
  538.     }//end if klude-linemode
  539.             
  540.  
  541.     if (ascii == '\015') //CR
  542.     {
  543.         //    If crmap is on, send CR-NULL instead of CR-LF.
  544.         netpush(tw->port);                    
  545.         if (tw->crmap) 
  546.             netwrite(tw->port,"\015\0",2);
  547.         else
  548.             netwrite(tw->port,"\015\012",2); //UNIVAC fix
  549.         if (tw->echo) 
  550.             parse(tw,(unsigned char *) "\012\015",2);    /* BYU LSC */
  551.         return;
  552.     }
  553.  
  554.     if (tw->echo && tw->halfdup) 
  555.         parse(tw, &ascii, 1);
  556.         
  557.     if (ascii != 255) 
  558.         netwrite(tw->port,&ascii,1);
  559.     else
  560.         netwrite(tw->port, "\377\377", 2);
  561.         
  562. }
  563.  
  564. void    HandleMouseDown(EventRecord myEvent)
  565. {
  566.     GrafPtr    whichWindow;
  567.     short    code, myRGMnum;
  568.     short     growErr, i;
  569.     code = FindWindow(myEvent.where, &whichWindow);
  570.     
  571.     switch (code) {
  572.         case inMenuBar:
  573.             if (myEvent.modifiers & optionKey)
  574.             {
  575.                 switchToOptionMenus(TRUE);
  576.                 HandleMenuCommand(MenuSelect(myEvent.where),myEvent.modifiers);    
  577.                 switchToOptionMenus(FALSE);
  578.             }
  579.             else if (myEvent.modifiers & shiftKey)
  580.             {
  581.                 switchToShiftMenus(TRUE);
  582.                 HandleMenuCommand(MenuSelect(myEvent.where),myEvent.modifiers);            
  583.                 switchToShiftMenus(FALSE);
  584.             }
  585.             else
  586.                 HandleMenuCommand(MenuSelect(myEvent.where),myEvent.modifiers);            
  587.             break;
  588.         case inSysWindow:
  589.             SystemClick(&myEvent, whichWindow);
  590.             break;
  591.         case inGoAway:
  592.             if (TrackGoAway( whichWindow, myEvent.where))
  593.                 CloseAWindow((WindowPtr)whichWindow);
  594.             break;
  595.  
  596.         case inDrag:
  597.             if ((whichWindow != FrontWindow()) &&
  598.                     (!(myEvent.modifiers & cmdKey)) &&
  599.                     (!(myEvent.modifiers & optionKey))) {
  600.                 SelectWindow(whichWindow);
  601.                 }
  602.             DragWindow(whichWindow, myEvent.where, &TelInfo->dragRect);
  603.             break;
  604.  
  605.         case inZoomIn:
  606.         case inZoomOut:
  607.             if (TrackBox( whichWindow, myEvent.where, code))
  608.                 RSzoom( whichWindow, code, myEvent.modifiers & shiftKey);
  609.             break;
  610.     
  611.     /* NCSA: SB - Telnet now allows you to grow the TEK window, finally.        */
  612.     /* NCSA: SB - So check to see if the click was in a TEK window                */
  613.     
  614.         case inGrow:
  615.             growErr = RSsize( whichWindow, (long *) &myEvent.where, myEvent.modifiers);
  616.             switch(growErr) {
  617.             case (-4):         /*bad mem problems, kill window, signal user */                
  618.                 OutOfMemory(-4);
  619.                 if ((i = WindowPtr2ScreenIndex(whichWindow)) >= 0) 
  620.                 {
  621.                     netclose(screens[i].port);
  622.                     removeport(&screens[i]);
  623.                 }
  624.                 break;
  625.             case (-2):        /* no resize due to memory error, signal user */
  626.                 OutOfMemory(-2);
  627.                 break;
  628.             default:         /* ok resize, or window not found */
  629.                 break;
  630.             }
  631.             myRGMnum = RGfindbywind(whichWindow);            /* NCSA: SB - is it a TEK window click? */
  632.             if (myRGMnum  != -1)            /* NCSA: SB - Anyone want to play some BOLO? */
  633.                 {                                            /* NCSA: SB */
  634.                 RGMgrowme((short)myRGMnum, whichWindow,(long *) &myEvent.where,myEvent.modifiers);    /* NCSA: TG */
  635.                 }                                            /* NCSA: SB */
  636.         break;
  637.         
  638.         case inContent:
  639.             if (whichWindow != FrontWindow()) {
  640.                 SelectWindow(whichWindow);
  641.                 }
  642.             else
  643.                 if (RSclick(whichWindow, myEvent) <0) {
  644.                     SetPort(whichWindow);
  645.                     GlobalToLocal(&myEvent.where);
  646.                     RGmousedown(whichWindow, &myEvent.where );
  647.                     }
  648.             break;
  649.         
  650.         default:
  651.             break;
  652.     }
  653. }
  654.  
  655. #pragma profile off
  656. void    DoEvents( void)
  657. {
  658.     Boolean        gotOne;            /* Did we get an event */
  659.     short        vs;
  660.     EventRecord    myEvent;
  661.     
  662.     gotOne = WaitNextEvent(everyEvent, &myEvent, gApplicationPrefs->TimeSlice, 0L);
  663.  
  664.     if (gotOne) 
  665.     {
  666.  
  667. /* BYU 2.4.11 - Turn the cursor off when the human makes the slightest move. */
  668.         if (gApplicationPrefs->BlinkCursor) 
  669.         {                                
  670.             if ( (vs=RSfindvwind(FrontWindow())) >= 0)    
  671.                 if (vs == screens[scrn].vs)                
  672.                     if (!(myEvent.modifiers & cmdKey) &&    
  673.                         ((myEvent.what == keyDown) || (myEvent.what == autoKey)))
  674.                         RScursblinkon(vs);                
  675.                     else                                
  676.                         RScursblinkoff(vs);                
  677.         }
  678.         HandleEvent(&myEvent);
  679.     }
  680.     else if (gApplicationPrefs->BlinkCursor && !TelInfo->suspended) 
  681.     {    /* BYU 2.4.11 */
  682.         if ( (vs=RSfindvwind(FrontWindow())) >= 0)        /* BYU 2.4.11 */
  683.             if (vs == screens[scrn].vs)                    /* BYU 2.4.11 */
  684.                 RScursblink(vs);                        /* BYU 2.4.11 */
  685.     }                                                    /* BYU 2.4.11 */
  686.     updateCursor(0);
  687. }                        
  688.  
  689. static long currentScript, defaultKCHR, mungeCount;
  690. static Boolean haveChangedKCHR;
  691. //called at startup to figure out the default roman KCHR and the active script
  692. void scriptKbdInit(void)
  693. {
  694.     currentScript = GetScriptManagerVariable(smKeyScript);//get active script
  695.     defaultKCHR = GetScriptVariable(smRoman, smScriptKeys); //get the smRoman default KCHR
  696.     mungeCount = GetScriptManagerVariable(smMunged); //Get the mungeCount
  697.     haveChangedKCHR = FALSE;
  698. }
  699.  
  700. void SetDefaultKCHR(void)
  701. {
  702.     if (haveChangedKCHR)
  703.     {
  704.         SetScriptVariable(smRoman,smScriptKeys,defaultKCHR);
  705.         haveChangedKCHR = FALSE;
  706.         KeyScript(smRoman);    
  707.     }
  708. }
  709. void CheckDefaultScriptSettings(void)
  710. {
  711.     long tempLong;
  712.     tempLong = GetScriptManagerVariable(smMunged);
  713.     if (tempLong > mungeCount)
  714.     {
  715.         currentScript = GetScriptManagerVariable(smKeyScript);//get the new active script
  716.         if ((currentScript != smRoman)&&(haveChangedKCHR)) //roman has been switched out and we need to fix it
  717.         {    
  718.             SetScriptVariable(smRoman,smScriptKeys,defaultKCHR);
  719.             currentScript = GetScriptManagerVariable(smKeyScript);//get the new active script
  720.             haveChangedKCHR = FALSE; //we dont mess with non-roman scripts    
  721.         }
  722.         mungeCount = tempLong;  //update the mungeCount
  723.     }
  724. }
  725.  
  726.  
  727. void HandleEvent(EventRecord *myEvent) //CCP split this from DoEvents so we can call this from
  728. {                                        //other places
  729.     short i,vs;
  730.     
  731.     switch(myEvent->what) {
  732.     case mouseDown:
  733.         HandleMouseDown(*myEvent);
  734.         break;
  735.  
  736.     case updateEvt:
  737.         switch(((WindowPeek)myEvent->message)->windowKind) {
  738.             case WIN_CONSOLE:
  739.             case WIN_LOG:
  740.             case WIN_CNXN:
  741.                 if (RSupdate((GrafPtr) myEvent->message))
  742.                     putln("Ack, problem in update!");
  743.                 break;
  744.             
  745.             case WIN_ICRG:
  746.                 if (MacRGupdate((WindowPtr) myEvent->message))
  747.                     putln("Ack, problem in update!");
  748.                 break;
  749.                 
  750.             case WIN_TEK:
  751.                 if (RGupdate((GrafPtr) myEvent->message) ==0) 
  752.                     TekDisable(RGgetVG((GrafPtr) myEvent->message));
  753.                 else
  754.                     putln("Ack, problem in update!");
  755.                 break;
  756.             
  757.             default:
  758.                 putln("Bad windowkind!");
  759.                 break;
  760.             }            
  761.         break;
  762.  
  763.     case keyDown:
  764.     case autoKey:
  765.         HandleKeyDown(*myEvent, &screens[scrn]);        /* All key events are processed through here */
  766.         break;
  767.  
  768.     case diskEvt:            /* check to see if disk needs to be initialized */
  769.         myEvent->where.h = 100;
  770.         myEvent->where.v = 120;
  771.         if (noErr != (( myEvent->message >> 16 ) & 0xffff )) {    /* check hi word */
  772.             DILoad();
  773.             DIBadMount( myEvent->where, myEvent->message);    /* BYU LSC */
  774.             DIUnload();
  775.         }
  776.         break;
  777.  
  778.     case activateEvt:
  779.         if ((myEvent->modifiers & activeFlag)==1)  //its an activate event
  780.         {
  781.             i=WindowPtr2ScreenIndex((GrafPtr) myEvent->message);    // We need to know who 
  782.             CheckDefaultScriptSettings(); //see if someone has changed the script
  783.             
  784.             //this next bit takes care of setting the KCHR based on the EMACS hack pref
  785.             if ((currentScript == smRoman)&&(screens[i].emacsmeta == 2))
  786.             {
  787.                 if (!haveChangedKCHR) //if we haven't already done this
  788.                 {
  789.                     SetScriptVariable(currentScript,smScriptKeys,502); //set the KCHR for EMACS
  790.                     KeyScript(smRoman);    //Make it active
  791.                     haveChangedKCHR = TRUE;
  792.                 }
  793.             }
  794.             else if (haveChangedKCHR) //new active window doesnt want EMACS hack
  795.             {
  796.                 SetScriptVariable(currentScript,smScriptKeys,defaultKCHR); 
  797.                 KeyScript(smRoman);    
  798.                 haveChangedKCHR = FALSE;
  799.             }
  800.             AdjustMenus();
  801.             DrawMenuBar();
  802.             i=WindowPtr2ScreenIndex((GrafPtr) myEvent->message);    /* We need to know who */
  803.             if (i>=0) 
  804.             {
  805.                 if ((screens[i].curgraph>-1) && (!(myEvent->modifiers & optionKey)))
  806.                     detachGraphics(screens[i].curgraph);
  807.                 changeport(scrn,i);
  808.                 scrn=i;
  809.             }
  810.             if ((i=RSfindvwind((GrafPtr) myEvent->message))>=0) 
  811.             {
  812.                 if (RSTextSelected(i)) 
  813.                 {                    
  814.                     EnableItem(myMenus[Fil],FLprint);        
  815.                     EnableItem(myMenus[Edit],EDcopy);    
  816.                     EnableItem(myMenus[Edit],EDcopyt);        
  817.                 } 
  818.                 else 
  819.                 {                                
  820.                     DisableItem(myMenus[Fil],FLprint);    
  821.                     DisableItem(myMenus[Edit],EDcopy);        
  822.                     DisableItem(myMenus[Edit],EDcopyt);        
  823.                 }                                        
  824.                 RSactivate(i);
  825.                 TelInfo->myfrontwindow=(WindowPeek) myEvent->message;
  826.                 TelInfo->myfronttype=DEC_WINDOW;
  827.                 TelInfo->myfrontvs = i;
  828.                 TelInfo->myfrontRgn =0L;
  829.                 updateCursor(1);
  830.             } 
  831.             else 
  832.             {                    
  833.                 TelInfo->myfrontwindow=(WindowPeek) myEvent->message;
  834.                 TelInfo->myfronttype=TEK_WINDOW;
  835.                 TelInfo->myfrontRgn =0L;
  836.                 updateCursor(1);
  837.                 if ( (i = RGgetdnum((GrafPtr) myEvent->message)) >-1) 
  838.                 {
  839.                     if (( i = RGgetVS( i)) >-1) 
  840.                     {
  841.                         EnableItem(myMenus[Fil],FLprint);    // enable printing 
  842.                         EnableItem(myMenus[Edit],EDcopy);    // - enable copying 
  843.                         DisableItem(myMenus[Edit],EDcopyt);    
  844.                         i = findbyVS( i);
  845.                         changeport(scrn,i);
  846.                         scrn=i;
  847.                     }
  848.                 }
  849.             }
  850.         } 
  851.         else //its a disable event
  852.         {
  853.             short i;
  854.             AdjustMenus();
  855.             DrawMenuBar();
  856.             if ((i=RSfindvwind((GrafPtr) myEvent->message))>=0)
  857.                 RSdeactivate(i);
  858.             NoWindow();
  859.         }
  860.         break;
  861.     case osEvt:
  862.         switch(( myEvent->message >>24) &0xff) {    
  863.             case switchEvt:
  864.                 if (myEvent->message & 0x20)
  865.                     /*Convert clipboard here if necc. (it is not)*/;
  866.  
  867.                 if (myEvent->message & 0x1) {        /* Resume Event */
  868.                     GrafPtr window;
  869.  
  870.                     TelInfo->suspended = FALSE;                /* We are no longer in suspension */
  871.                     if (gHaveInstalledNotification)
  872.                     {
  873.                         NMRemove(nRecPtr);
  874.                         DisposeHandle(nRecPtr->nmIcon);
  875.                         gHaveInstalledNotification = FALSE;
  876.                     }
  877.                     DisableItem( myMenus[Edit],EDcut);
  878.                     DisableItem( myMenus[Edit],EDundo);
  879.                     DisableItem( myMenus[Edit],EDclear);
  880.  
  881.                     window = FrontWindow();            /* Who's on first */
  882.                     if ( (vs=RSfindvwind(window)) >= 0) 
  883.                     {
  884.                         CheckDefaultScriptSettings();//update script settings
  885.                         if ((currentScript == smRoman)&&(haveChangedKCHR)) // set it back
  886.                         {
  887.                             SetScriptVariable(currentScript,smScriptKeys,502); //set the KCHR for EMACS
  888.                             KeyScript(smRoman);    //Make it active
  889.                         }
  890.                         RSactivate(vs);
  891.                         TelInfo->myfrontwindow = (WindowPeek) window;
  892.                         TelInfo->myfronttype=DEC_WINDOW;
  893.                         TelInfo->myfrontvs = vs;
  894.                         TelInfo->myfrontRgn =0L;
  895.                         updateCursor(1);
  896.                     } else if ( (long)window != 0L) {
  897.                         myEvent->message = (long) window;
  898.                         myEvent->modifiers |= activeFlag;
  899.                         myEvent->what = activateEvt;
  900.                         myEvent->when = TickCount();
  901.                         SystemEvent( myEvent);
  902.                         }
  903.                     }
  904.                 else {                                /* Suspend Event */
  905.                     GrafPtr window;
  906.                     CheckDefaultScriptSettings();//update script settings
  907.                     if ((currentScript == smRoman)&&(haveChangedKCHR)) //switch out to default KCHR when while suspended
  908.                     {
  909.                         SetScriptVariable(currentScript,smScriptKeys,defaultKCHR); 
  910.                         KeyScript(smRoman);    
  911.                     }
  912.                     TelInfo->suspended=TRUE;                    /* We be in waitin' */
  913.                     EnableItem( myMenus[Edit],EDcut);
  914.                     EnableItem( myMenus[Edit],EDundo);
  915.                     EnableItem( myMenus[Edit],EDclear);
  916.  
  917.                     window = FrontWindow();            /* Who's on first */
  918.                     if ((window = FrontWindow()) != nil) {
  919.                         if ( (vs=RSfindvwind(window)) >= 0)
  920.                             RSdeactivate(vs);
  921.                         else if ( (long)window != 0L) {
  922.                             myEvent->message = (long) window;
  923.                             myEvent->modifiers &= (~activeFlag);
  924.                             myEvent->what = activateEvt;
  925.                             myEvent->when = TickCount();
  926.                             SystemEvent( myEvent);
  927.                             }
  928.                         }
  929.                     NoWindow();
  930.                     }
  931.                 break;            /* switch of myEvent->message >>24 */
  932.             default:
  933.                 break;
  934.             }
  935.         break;
  936.     case kHighLevelEvent:
  937.         (void) AEProcessAppleEvent(myEvent);
  938.         break;            
  939.     }
  940.  
  941. }
  942. //#pragma profile on
  943.  
  944. void    CloseAWindow(WindowPtr    theWindow)
  945. {
  946.     short    i;
  947.     long junk;
  948.     
  949.     switch(((WindowPeek)theWindow)->windowKind) {
  950.         case WIN_CONSOLE:
  951. //            Debugger();                // Can't close the console window
  952.             break;
  953.                     
  954.         case WIN_LOG:
  955.             if (theWindow == ftplog->wind) {
  956.                 CheckItem(myMenus[Fil],FLlog,FALSE);
  957.                 TelInfo->ftplogon = FALSE;
  958.                 RShide(ftplog->vs);
  959.             }
  960.             break;
  961.                     
  962.         case WIN_CNXN:
  963.             if ((i = WindowPtr2ScreenIndex(theWindow)) >= 0) 
  964.             {
  965.                 if ( screens[i].active == CNXN_ISCORPSE)
  966.                     destroyport(i);
  967.                 else 
  968.                 {
  969.                     if ( !ReallyClose( i) ) break;
  970.                     netclose(screens[i].port);
  971.                     removeport(&screens[i]);
  972.                 }
  973.             }
  974.             break;
  975.         
  976.         case WIN_ICRG:
  977.             MacRGdestroy(MacRGfindwind(theWindow));
  978.             MaxMem(&junk);
  979.             break;
  980.             
  981.         case WIN_TEK:
  982.             destroyGraphics(RGgetVG(theWindow));
  983.             MaxMem(&junk);
  984.             break;
  985.         
  986.         default:
  987.             DebugStr("\pBad windowkind!");
  988.             break;
  989.         }            
  990.  
  991.         NoWindow();
  992. }
  993.  
  994.  
  995. void NotifyUser (void)
  996. {
  997.     OSErr err = noErr;
  998.  
  999.     if ((!TelInfo->suspended)||(!gApplicationPrefs->NotifyUser)||gHaveInstalledNotification)
  1000.         return;
  1001.     
  1002.     nRecPtr = (NMRecPtr) myNewPtr(sizeof(NMRec)); 
  1003.     if (nRecPtr == NULL)
  1004.         return;
  1005.     nRecPtr->qType = nmType;
  1006.     nRecPtr->nmMark = 1;
  1007.     err = GetIconSuite(&(nRecPtr->nmIcon), kNCSAIconFamilyId, svAllSmallData);
  1008.     if (err != noErr) nRecPtr->nmIcon = nil;
  1009.     nRecPtr->nmSound = nil;
  1010.     nRecPtr->nmStr = nil;
  1011.     nRecPtr->nmResp = nil;
  1012.     NMInstall(nRecPtr);
  1013.     gHaveInstalledNotification = TRUE;
  1014. }
  1015.